/* ========================================================================
 * Bootstrap: modal.js v3.0.0
 * http://twbs.github.com/bootstrap/javascript.html#modals
 * ========================================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */

define(function(require, exports, module) {
    return function(jquery){
        +function ($) { "use strict";

            // MODAL CLASS DEFINITION
            // ======================

            var Modal = function (element, options) {
                this.options   = options
                this.$element  = $(element)
                this.$backdrop =
                    this.isShown   = null

                if (this.options.remote) this.$element.load(this.options.remote)
            }

            Modal.DEFAULTS = {
                backdrop: true
                , keyboard: true
                , show: true
            }

            Modal.prototype.toggle = function (_relatedTarget) {
                return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
            }
            Modal.prototype.setCenterPos=function(){
                var that=this;
                var winInfo=that._setCenter();
                //if(_top<0){
                //窗口基本信息
                if(this.$backdrop.css("position")=="fixed"){
                    var _top=(winInfo.h-that.$element.outerHeight())*0.5;
                }else{
                    var _top=winInfo.scrollY+(winInfo.h-that.$element.outerHeight())*0.5;
                    if(_top < $(window).scrollTop()) {
                        _top=30 + $(window).scrollTop();
                    }
                }
                that.$element.css({
                    "margin-top":0,
                    "margin-left":"-"+that.options.width*0.5+"px",
                    "top":_top+"px"
                })
                //进行width设定
            };
            Modal.prototype.center=function(){
                this.setCenterPos();
            };
            Modal.prototype._setCenter=function(){
                var winInfo={};
                var de=document.documentElement;
                winInfo.h=self.innerHeight||(de&&de.clientHeight)||document.body.clientHeight;
                winInfo.w=self.innerWidth||(de&&de.clientWidth)||document.body.clientWidth;
                winInfo.scrollX=self.pageXOffset||(de&&de.scrollLeft)||document.body.scrollLeft;
                winInfo.scrollY=self.pageYoffset||(de&&de.scrollTop)||document.body.scrollTop;
                return winInfo;
            }
            Modal.prototype.show = function (_relatedTarget) {
                var that = this
                var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })

                this.$element.trigger(e)
                if (this.isShown || e.isDefaultPrevented()) return

                this.isShown = true

                this.escape();
                //进行弹层的打开，兼容jqueryui
                if(that.options.open){
                    if(typeof(that.options.open)=="string"){
                        var openCallback=that.options.open;
                        if(openCallback.indexOf(".")>-1){
                            var openArray=openCallback.split(".");
                            window[openArray[0]][openArray[1]].call(that);
                        }else{
                            window[openCallback].call(that);
                        }
                    }else{
                        that.options.open.call(that);
                    }
                }

                this.$element.on('click.dismiss.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))

                this.backdrop(function () {
                    var transition = $.support.transition && that.$element.hasClass('fade')

                    if (!that.$element.parent().length) {
                        that.$element.appendTo(document.body) // don't move modals dom position
                    }

                    that.$element.show();
                    that.setCenterPos();
                    if (transition) {
                        that.$element[0].offsetWidth // force reflow
                    }

                    that.$element
                        .addClass('in')
                        .attr('aria-hidden', false)

                    that.enforceFocus()

                    var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })

                    transition ?
                        that.$element.find('.modal-dialog') // wait for modal to slide in
                            .one($.support.transition.end, function () {
                                that.$element.focus().trigger(e)
                            })
                            .emulateTransitionEnd(300) :
                        that.$element.focus().trigger(e)
                })
            }

            Modal.prototype.hide = function (e) {
                if (e) e.preventDefault()
                e = $.Event('hide.bs.modal')

                this.$element.trigger(e)

                if (!this.isShown || e.isDefaultPrevented()) return
                this.isShown = false

                this.escape()

                $(document).off('focusin.bs.modal')

                this.$element
                    .removeClass('in')
                    .attr('aria-hidden', true)
                    .off('click.dismiss.modal')

                $.support.transition && this.$element.hasClass('fade') ?
                    this.$element
                        .one($.support.transition.end, $.proxy(this.hideModal, this))
                        .emulateTransitionEnd(300) :
                    this.hideModal()
            }

            Modal.prototype.enforceFocus = function () {
                $(document)
                    .off('focusin.bs.modal') // guard against infinite focus loop
                    .on('focusin.bs.modal', $.proxy(function (e) {
                        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
                            this.$element.focus()
                        }
                    }, this))
            }

            Modal.prototype.escape = function () {
                if (this.isShown && this.options.keyboard) {
                    this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
                        e.which == 27 && this.hide()
                    }, this))
                } else if (!this.isShown) {
                    this.$element.off('keyup.dismiss.bs.modal')
                }
            }

            Modal.prototype.hideModal = function () {
                var that = this
                this.$element.hide()
                this.backdrop(function () {
                    that.removeBackdrop()
                    that.$element.trigger('hidden.bs.modal');

                    if(that.options.close){
                        if(typeof(that.options.close)=="string"){
                            var closeCallback=that.options.close;
                            if(closeCallback.indexOf(".")>-1){
                                var closeArray=closeCallback.split(".");
                                window[closeArray[0]][closeArray[1]].call(that);
                            }else{
                                window[closeCallback].call(that);
                            }
                        }else{
                            that.options.close.call(that);
                        }
                    }
                })
            }

            Modal.prototype.removeBackdrop = function () {
                this.$backdrop && this.$backdrop.remove()
                this.$backdrop = null
            }

            Modal.prototype.backdrop = function (callback) {
                var that    = this
                var animate = this.$element.hasClass('fade') ? 'fade' : ''

                if (this.isShown && this.options.backdrop) {
                    var doAnimate = $.support.transition && animate
                    var hasID=this.$element[0].id;
                    if(!hasID){
                        hasID="";
                    }
                    this.$backdrop = $('<div class="modal-backdrop ' + animate + '" id="J_backdrop_'+hasID+'" />')
                        .appendTo(document.body)

                    this.$element.on('click.dismiss.modal', $.proxy(function (e) {
                        if (e.target !== e.currentTarget) return
                        this.options.backdrop == 'static'
                            ? this.$element[0].focus.call(this.$element[0])
                            : this.hide.call(this)
                    }, this))

                    if (doAnimate) this.$backdrop[0].offsetWidth // force reflow

                    this.$backdrop.addClass('in')

                    if (!callback) return

                    doAnimate ?
                        this.$backdrop
                            .one($.support.transition.end, callback)
                            .emulateTransitionEnd(150) :
                        callback()

                } else if (!this.isShown && this.$backdrop) {
                    this.$backdrop.removeClass('in')

                    $.support.transition && this.$element.hasClass('fade')?
                        this.$backdrop
                            .one($.support.transition.end, callback)
                            .emulateTransitionEnd(150) :
                        callback()

                } else if (callback) {
                    callback()
                }
            }


            // MODAL PLUGIN DEFINITION
            // =======================

            var old = $.fn.modal

            $.fn.modal = function (option, _relatedTarget) {
                return this.each(function () {
                    var $this   = $(this)
                    var data    = $this.data('bs.modal')
                    var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)

                    if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
                    if (typeof option == 'string') data[option](_relatedTarget)
                    else if (options.show) data.show(_relatedTarget)
                })
            }

            $.fn.modal.Constructor = Modal


            // MODAL NO CONFLICT
            // =================

            $.fn.modal.noConflict = function () {
                $.fn.modal = old
                return this
            }


            // MODAL DATA-API
            // ==============

            $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
                var $this   = $(this)
                var href    = $this.attr('href')
                var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
                var option  = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())

                e.preventDefault()

                $target
                    .modal(option, this)
                    .one('hide', function () {
                        $this.is(':visible') && $this.focus()
                    })
            })

            $(document)
                .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })
                .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })

        }(window.jQuery);
    }
});
